#include "evaluate.h"
#include "stdio.h"
extern params InitParams;
extern int intrinsicValue[];
/* Currently Positional value is determined as a weighted product of number of free squares available
for the piece, need to include more positional aspects like distance from centre, open files, control over ranks etc
*/
void calcPosVal(boardState *pbs, int myidx, int numFreesquares){
	// found that it is better to decrease the weightage here 
	pbs->pieces[myidx].vpos += InitParams.a1*numFreesquares;
	return;
}
/* Calculates the total value as weighted sum of positional, intrinsic and dynamic strenghts */
void calcTotVal(boardState *pbs, int pieceidx){
	float vint,vdyn,wint,wdyn,vpos,wpos;
	if(pbs->pieces[pieceidx].isalive){
		vint = pbs->pieces[pieceidx].vint;
		vdyn = pbs->pieces[pieceidx].vdyn;
		vpos = pbs->pieces[pieceidx].vpos;
		wdyn = pbs->pieces[pieceidx].wdyn;
		wint = pbs->pieces[pieceidx].wint;
		wpos = pbs->pieces[pieceidx].wpos;
		pbs->pieces[pieceidx].tot_value = vint * wint + vdyn * wdyn + vpos * wpos;
	}
	return;
}

/* Analyze possible immediate attacks and see if the piece can get potential get captured by the opponent */
int analyzeCapture(boardState *pbs, int pieceidx)
{
	int current_val = pbs->pieces[pieceidx].vint;
	int sorted_attackers[32];
	int sorted_defenders[32];
	int num_attackers=0;
	int num_defenders=0;
	int best_attacker, best_defender,i;
	int j, insert_idx;

	for(i=0;i<32;i++)
	{
		sorted_attackers[i] = sorted_defenders[i] = 1234567;
	}
	
	for(i=0;i<32;i++)
	{
		if(pbs->pieces[pieceidx].enemyAttackingidxflag[i] == 1)
		{
			j = 0;
			while(pbs->pieces[i].vint > sorted_attackers[j])
				j++;
			insert_idx = j;
			for(j= num_attackers-1; j >= insert_idx ; j++){
				sorted_attackers[j+1] = sorted_attackers[j];
			}
			sorted_attackers[insert_idx] = pbs->pieces[i].vint;
			num_attackers++;
		}
	}
	for(i=0;i<32;i++)
	{
		if(pbs->pieces[pieceidx].friendDefendingidxflag[i] == 1)
		{
			j = 0;
			while(pbs->pieces[i].vint > sorted_defenders[j])
				j++;
			insert_idx = j;
			for(j= num_defenders-1; j >= insert_idx ; j++){
				sorted_defenders[j+1] = sorted_defenders[j];
			}
			sorted_defenders[insert_idx] = pbs->pieces[i].vint;
			num_defenders++;
		}
	}
}
// april 3rd version - performing good
/* Calculate dynamic value of a piece based on threads and attacking options */
void calcDynVal(boardState *pbs,int pieceidx)
{

	int playeridx = (pieceidx < 16)?0:1;
	int enemyidx = 1-playeridx;
	
	int otherpieceidx_start = enemyidx * 16;
	int otherpieceidx_end = otherpieceidx_start + 15;
	
	int friendpieceidx_start = playeridx * 16;
	int friendpieceidx_end = playeridx * 16 + 15;

	int currpos,otherpieceidx;
	
	int num_attackers = 0, num_defenders = 0;
	float biggest_attacker_val, smallest_attacker_val;
	float biggest_defender_val, smallest_defender_val;
	int biggest_attacker_type = -1, smallest_attacker_type = -1;
	int biggest_defender_type = -1, smallest_defender_type = -1;
	int i;
	int no_attacked,no_defended;
	int capture_Val;
	int total_attacker_val, total_defender_val;

	currpos = pbs->pieces[pieceidx].squareidx;

	// find total number of pieces attacking a given piece
	biggest_attacker_val = -1;
	smallest_attacker_val = 100000;
	pbs->pieces[pieceidx].vdyn = 0;
	total_attacker_val = 0;
	for(otherpieceidx = otherpieceidx_start; otherpieceidx <= otherpieceidx_end; otherpieceidx ++)
	{
		if(hasInfluence(pbs,otherpieceidx,currpos))
		{
			num_attackers ++;
			if(pbs->pieces[otherpieceidx].tot_value > biggest_attacker_val)
			{
				biggest_attacker_val = pbs->pieces[otherpieceidx].vint;
				biggest_attacker_type = pbs->pieces[otherpieceidx].piecetype;
			}
			total_attacker_val += pbs->pieces[otherpieceidx].vint;
		}
	}
	total_defender_val =  pbs->pieces[pieceidx].vint;
	for(otherpieceidx = friendpieceidx_start; otherpieceidx <= friendpieceidx_start; otherpieceidx ++)
	{
		if(hasInfluence(pbs,otherpieceidx,currpos))
		{
			num_defenders ++;
			if(pbs->pieces[otherpieceidx].tot_value > biggest_attacker_val)
			{
				biggest_defender_val = pbs->pieces[otherpieceidx].vint;
				biggest_defender_type = pbs->pieces[otherpieceidx].piecetype;
			}
			total_defender_val += pbs->pieces[otherpieceidx].vint;
		}
	}
	if(num_defenders > 0)
	{
		if(num_attackers > num_defenders)
		{
			//pbs->pieces[pieceidx].tot_value = 0;
			pbs->pieces[pieceidx].vdyn = 0;
		}
		else if(num_attackers == num_defenders) 
		{
			if(biggest_defender_type == KING)
			{
				//pbs->pieces[pieceidx].tot_value = 0;
				pbs->pieces[pieceidx].vdyn = -intrinsicValue[KING];
			}
			else
			{
				pbs->pieces[pieceidx].vdyn = total_attacker_val - total_defender_val;			
			}
		}
		else
		{
			// number of defenders is more than number of attackers
			// hence the piece is safe .. 
			pbs->pieces[pieceidx].vdyn = pbs->pieces[pieceidx].vint;			
		}
	}
	else
	{
		if(num_attackers > 0)
		{
			pbs->pieces[pieceidx].vdyn = 0;
		}
		else
			pbs->pieces[pieceidx].vdyn = pbs->pieces[pieceidx].vint;
	}

	// find the number of unattacked squares available for the piece to move
	no_attacked = 0;
	no_defended = 0;
	for(i=0;i<pbs->pieces[pieceidx].numLegal;i++){
		// find how many time the legal move sqaures for a give piece are attacked by enemy pieces
		for(otherpieceidx = otherpieceidx_start; otherpieceidx <= otherpieceidx_end;otherpieceidx++){
			if(hasInfluence(pbs,otherpieceidx,pbs->pieces[pieceidx].legalMoves[i]))
				no_attacked ++;
		}
		// find how many times the legal move sqaures for a give piece are defended by friendly pieces
		for(otherpieceidx = friendpieceidx_start; otherpieceidx <= friendpieceidx_end;otherpieceidx++){
			if(otherpieceidx !=pieceidx){
				if(hasInfluence(pbs,otherpieceidx,pbs->pieces[pieceidx].legalMoves[i]))
					no_defended ++;
			}
		}
	}
	pbs->pieces[pieceidx].vpos += InitParams.a2*(no_defended - no_attacked);
	//capture_Val = analyzeCapture(pbs,pieceidx);
	
}

